// Package macro 实现宏观演化引擎
// 基于四维一体法则的第三维度：宏观演化
package macro

import (
	"fmt"
	"math"
	"math/rand"
	"time"
)

// System 系统结构
type System struct {
	ID         string
	Parameters map[string]float64
	Fitness    float64
	Generation int
	Created    time.Time
	Modified   time.Time
}

// Environment 环境结构
type Environment struct {
	Temperature    float64            // 温度 (18-22℃)
	LightLevel     float64            // 光照 (50-200 lux)
	EMFLevel       float64            // 电磁水平
	Constraints    map[string]float64 // 环境约束
	OptimalRanges  map[string][]float64
}

// EvolutionSnapshot 演化快照
type EvolutionSnapshot struct {
	Generation   int
	BestFitness  float64
	AvgFitness   float64
	Diversity    float64
	Timestamp    time.Time
	BestSystem   *System
}

// EvolutionEngine 演化引擎
type EvolutionEngine struct {
	GenerationCount int                         // 代数计数
	MutationRate    float64                     // 变异率 (0-1)
	PopulationSize  int                         // 种群大小
	FitnessFunction func(*System) float64       // 适应度函数
	Population      []*System                   // 当前种群
	EvolutionPath   []EvolutionSnapshot         // 演化路径
	BestSystem      *System                     // 最佳系统
	rng             *rand.Rand
}

// NewEvolutionEngine 创建新的演化引擎
func NewEvolutionEngine(populationSize int, mutationRate float64) *EvolutionEngine {
	return &EvolutionEngine{
		GenerationCount: 0,
		MutationRate:    mutationRate,
		PopulationSize:  populationSize,
		Population:      make([]*System, 0, populationSize),
		EvolutionPath:   make([]EvolutionSnapshot, 0),
		rng:             rand.New(rand.NewSource(time.Now().UnixNano())),
	}
}

// SetFitnessFunction 设置适应度函数
func (e *EvolutionEngine) SetFitnessFunction(fn func(*System) float64) {
	e.FitnessFunction = fn
}

// Initialize 初始化种群
func (e *EvolutionEngine) Initialize(paramRanges map[string][]float64) error {
	if e.FitnessFunction == nil {
		return fmt.Errorf("必须先设置适应度函数")
	}

	e.Population = make([]*System, e.PopulationSize)
	for i := 0; i < e.PopulationSize; i++ {
		system := e.createRandomSystem(paramRanges)
		system.Fitness = e.FitnessFunction(system)
		e.Population[i] = system
	}

	e.updateBestSystem()
	return nil
}

// Evolve 执行一代演化
func (e *EvolutionEngine) Evolve() (*EvolutionSnapshot, error) {
	if len(e.Population) == 0 {
		return nil, fmt.Errorf("种群未初始化")
	}

	// 1. 评估当前种群
	for _, sys := range e.Population {
		sys.Fitness = e.FitnessFunction(sys)
	}

	// 2. 选择
	parents := e.selection()

	// 3. 交叉
	offspring := e.crossover(parents)

	// 4. 变异
	e.mutation(offspring)

	// 5. 评估新个体
	for _, sys := range offspring {
		sys.Fitness = e.FitnessFunction(sys)
	}

	// 6. 替换（精英保留策略）
	e.replacement(offspring)

	// 7. 更新代数和统计信息
	e.GenerationCount++
	e.updateBestSystem()

	// 8. 记录演化快照
	snapshot := e.createSnapshot()
	e.EvolutionPath = append(e.EvolutionPath, snapshot)

	return &snapshot, nil
}

// EvolveGenerations 演化多代
func (e *EvolutionEngine) EvolveGenerations(numGenerations int) ([]*EvolutionSnapshot, error) {
	snapshots := make([]*EvolutionSnapshot, 0, numGenerations)

	for i := 0; i < numGenerations; i++ {
		snapshot, err := e.Evolve()
		if err != nil {
			return snapshots, err
		}
		snapshots = append(snapshots, snapshot)
	}

	return snapshots, nil
}

// AdaptToEnvironment 适应环境变化
func (e *EvolutionEngine) AdaptToEnvironment(env *Environment) error {
	if env == nil {
		return fmt.Errorf("环境不能为空")
	}

	// 根据环境调整变异率
	if env.Temperature < 18 || env.Temperature > 22 {
		// 温度不适宜，增加变异以快速适应
		e.MutationRate = math.Min(e.MutationRate*1.5, 0.3)
	} else {
		// 温度适宜，降低变异率以稳定演化
		e.MutationRate = math.Max(e.MutationRate*0.8, 0.01)
	}

	// 根据光照调整种群多样性
	if env.LightLevel > 200 {
		// 光照过强，可能影响量子相干性，增加多样性保护
		e.ensureDiversity(0.3)
	}

	// 根据电磁水平调整适应策略
	if env.EMFLevel > 0.1 {
		// 电磁干扰过强，引入保护机制
		e.applyEMFProtection()
	}

	return nil
}

// CalculateFitness 计算系统适应度
func (e *EvolutionEngine) CalculateFitness(system *System) float64 {
	if e.FitnessFunction != nil {
		return e.FitnessFunction(system)
	}
	return e.defaultFitnessFunction(system)
}

// TrackEvolutionPath 获取演化路径
func (e *EvolutionEngine) TrackEvolutionPath() []EvolutionSnapshot {
	return e.EvolutionPath
}

// GetBestSystem 获取最佳系统
func (e *EvolutionEngine) GetBestSystem() *System {
	return e.BestSystem
}

// GetEvolutionReport 获取演化报告
func (e *EvolutionEngine) GetEvolutionReport() map[string]interface{} {
	avgFitness, diversity := e.calculatePopulationStats()

	return map[string]interface{}{
		"generation":      e.GenerationCount,
		"population_size": len(e.Population),
		"best_fitness":    e.BestSystem.Fitness,
		"avg_fitness":     avgFitness,
		"diversity":       diversity,
		"mutation_rate":   e.MutationRate,
		"evolution_path":  len(e.EvolutionPath),
	}
}

// 内部方法

func (e *EvolutionEngine) createRandomSystem(paramRanges map[string][]float64) *System {
	system := &System{
		ID:         fmt.Sprintf("sys_%d_%d", e.GenerationCount, e.rng.Intn(100000)),
		Parameters: make(map[string]float64),
		Generation: e.GenerationCount,
		Created:    time.Now(),
		Modified:   time.Now(),
	}

	for param, r := range paramRanges {
		min, max := r[0], r[1]
		system.Parameters[param] = min + e.rng.Float64()*(max-min)
	}

	return system
}

func (e *EvolutionEngine) selection() []*System {
	// 锦标赛选择
	tournamentSize := 3
	parents := make([]*System, e.PopulationSize)

	for i := 0; i < e.PopulationSize; i++ {
		best := e.Population[e.rng.Intn(len(e.Population))]
		for j := 1; j < tournamentSize; j++ {
			candidate := e.Population[e.rng.Intn(len(e.Population))]
			if candidate.Fitness > best.Fitness {
				best = candidate
			}
		}
		parents[i] = best
	}

	return parents
}

func (e *EvolutionEngine) crossover(parents []*System) []*System {
	offspring := make([]*System, 0, e.PopulationSize)

	for i := 0; i < e.PopulationSize-1; i += 2 {
		parent1 := parents[i]
		parent2 := parents[i+1]

		child1, child2 := e.uniformCrossover(parent1, parent2)
		offspring = append(offspring, child1, child2)
	}

	return offspring
}

func (e *EvolutionEngine) uniformCrossover(p1, p2 *System) (*System, *System) {
	child1 := &System{
		ID:         fmt.Sprintf("sys_%d_%d", e.GenerationCount, e.rng.Intn(100000)),
		Parameters: make(map[string]float64),
		Generation: e.GenerationCount + 1,
		Created:    time.Now(),
		Modified:   time.Now(),
	}

	child2 := &System{
		ID:         fmt.Sprintf("sys_%d_%d", e.GenerationCount, e.rng.Intn(100000)),
		Parameters: make(map[string]float64),
		Generation: e.GenerationCount + 1,
		Created:    time.Now(),
		Modified:   time.Now(),
	}

	for param := range p1.Parameters {
		if e.rng.Float64() < 0.5 {
			child1.Parameters[param] = p1.Parameters[param]
			child2.Parameters[param] = p2.Parameters[param]
		} else {
			child1.Parameters[param] = p2.Parameters[param]
			child2.Parameters[param] = p1.Parameters[param]
		}
	}

	return child1, child2
}

func (e *EvolutionEngine) mutation(offspring []*System) {
	for _, sys := range offspring {
		if e.rng.Float64() < e.MutationRate {
			// 随机选择一个参数进行变异
			params := make([]string, 0, len(sys.Parameters))
			for param := range sys.Parameters {
				params = append(params, param)
			}

			if len(params) > 0 {
				mutParam := params[e.rng.Intn(len(params))]
				// 高斯变异
				sys.Parameters[mutParam] += e.rng.NormFloat64() * 0.1
				sys.Modified = time.Now()
			}
		}
	}
}

func (e *EvolutionEngine) replacement(offspring []*System) {
	// 合并父代和子代
	combined := append(e.Population, offspring...)

	// 按适应度排序
	for i := 0; i < len(combined); i++ {
		for j := i + 1; j < len(combined); j++ {
			if combined[j].Fitness > combined[i].Fitness {
				combined[i], combined[j] = combined[j], combined[i]
			}
		}
	}

	// 保留最优的N个
	e.Population = combined[:e.PopulationSize]
}

func (e *EvolutionEngine) updateBestSystem() {
	if len(e.Population) == 0 {
		return
	}

	best := e.Population[0]
	for _, sys := range e.Population {
		if sys.Fitness > best.Fitness {
			best = sys
		}
	}

	if e.BestSystem == nil || best.Fitness > e.BestSystem.Fitness {
		e.BestSystem = best
	}
}

func (e *EvolutionEngine) createSnapshot() EvolutionSnapshot {
	avgFitness, diversity := e.calculatePopulationStats()

	return EvolutionSnapshot{
		Generation:  e.GenerationCount,
		BestFitness: e.BestSystem.Fitness,
		AvgFitness:  avgFitness,
		Diversity:   diversity,
		Timestamp:   time.Now(),
		BestSystem:  e.BestSystem,
	}
}

func (e *EvolutionEngine) calculatePopulationStats() (avgFitness, diversity float64) {
	if len(e.Population) == 0 {
		return 0, 0
	}

	// 计算平均适应度
	for _, sys := range e.Population {
		avgFitness += sys.Fitness
	}
	avgFitness /= float64(len(e.Population))

	// 计算多样性（参数方差）
	for _, sys := range e.Population {
		diversity += math.Pow(sys.Fitness-avgFitness, 2)
	}
	diversity = math.Sqrt(diversity / float64(len(e.Population)))

	return avgFitness, diversity
}

func (e *EvolutionEngine) ensureDiversity(threshold float64) {
	_, diversity := e.calculatePopulationStats()
	if diversity < threshold {
		// 引入随机个体增加多样性
		numNew := e.PopulationSize / 10
		for i := 0; i < numNew; i++ {
			paramRanges := e.extractParamRanges()
			newSys := e.createRandomSystem(paramRanges)
			newSys.Fitness = e.FitnessFunction(newSys)
			// 替换最差的个体
			e.Population[len(e.Population)-1-i] = newSys
		}
	}
}

func (e *EvolutionEngine) applyEMFProtection() {
	// 降低变异率以保护量子态
	e.MutationRate = math.Max(e.MutationRate*0.5, 0.001)
}

func (e *EvolutionEngine) extractParamRanges() map[string][]float64 {
	ranges := make(map[string][]float64)

	if len(e.Population) == 0 {
		return ranges
	}

	for param := range e.Population[0].Parameters {
		min, max := math.MaxFloat64, -math.MaxFloat64
		for _, sys := range e.Population {
			val := sys.Parameters[param]
			if val < min {
				min = val
			}
			if val > max {
				max = val
			}
		}
		ranges[param] = []float64{min, max}
	}

	return ranges
}

func (e *EvolutionEngine) defaultFitnessFunction(system *System) float64 {
	// 默认适应度函数：参数和的倒数
	sum := 0.0
	for _, v := range system.Parameters {
		sum += math.Abs(v)
	}
	if sum == 0 {
		return 0
	}
	return 1.0 / sum
}
